﻿Imports System.Net
Imports System.Net.Mail
Imports System.IO
Imports System.Data.OleDb
Imports System.Web.Security
Imports Samples.AccessProviders
Imports System.Web
Imports LecturerAppointmentSystem
Imports LecturerAppointmentSystem.UserDetails
Public Class Register
    Inherits System.Web.UI.Page

    Public Const FaceBookAppKey As String = "255426577807393"
    Dim facebookName As String = ""
    Dim firstName As String = ""
    Dim lastName As String = ""
    Dim facebookId As String = ""
    Dim email As String = ""
    Dim json__1 As String
    Dim userEmail As String = ""
    Dim siteAddress As String = ""
    Dim allTheUsers As Array
    Dim allTheUniEmailIds As Array
    Dim allTheFbEmailIds As Array

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            RoleMultiView.SetActiveView(DefaultView)
        End If
        'If user hasn't logged in via facebook and still tries to register, redirect to login page
        If Request.Cookies("fbs_" + FaceBookAppKey) Is Nothing Then
            Response.Redirect("Login.aspx")
        Else
            Dim cookie As String = Request.Cookies("fbs_" + FaceBookAppKey).Value
            cookie = cookie.Replace("""", "")
            Dim facebookValues As NameValueCollection = HttpUtility.ParseQueryString(cookie)
            json__1 = GetFacebookUserJSON(facebookValues("uid"), facebookValues("access_token"))
            Dim jsonHash As Hashtable = DirectCast(JSON.JsonDecode(json__1), Hashtable)
            facebookName = TryCast(jsonHash("name"), String)
            firstName = TryCast(jsonHash("first_name"), String)
            lastName = TryCast(jsonHash("last_name"), String)
            facebookId = TryCast(jsonHash("id"), String)
            email = TryCast(jsonHash("email"), String)
        End If
        allTheUsers = getAllUsers()
        If doesUserExist(allTheUsers, facebookId) Then
            'User is already registered, redirect to login page
            Response.Redirect("Login.aspx")
        End If
    End Sub


    Protected Sub Role_Changed(ByVal sender As Object, ByVal e As System.EventArgs)
        If RadioButtonList1.SelectedValue = 3 Then
            RoleMultiView.SetActiveView(StudentView)
        ElseIf RadioButtonList1.SelectedValue = 2 Then
            RoleMultiView.SetActiveView(LecturerView)
        Else
            Throw New Exception("You did not select a valid option.")
        End If
    End Sub

    'Private Shared Function GetFacebookUserJSON(ByVal userid As String, ByVal access_token As String) As String
    '    Dim url As String = String.Format("https://graph.facebook.com/{0}?access_token={1}&fields=email,name,first_name,last_name,link", userid, access_token)

    '    Dim wc As New WebClient()
    '    Dim data As Stream = wc.OpenRead(url)
    '    Dim reader As New StreamReader(data)
    '    Dim s As String = reader.ReadToEnd()
    '    data.Close()
    '    reader.Close()

    '    Return s
    'End Function

    Protected Sub btn_submit_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btn_submit.Click
        allTheUsers = getAllUsers()
        If Page.IsValid Then
            CreateNewUser()
            Session("UserName") = tb_username.Text
            Session("UniEmail") = tb_uniEmail.Text
            Response.Redirect("emailsent.aspx")
            'Response.Redirect("Default.aspx?username=" & tb_username.Text)
        Else
            Response.Write("Please enter all the required fields")
        End If

    End Sub

    Sub CreateNewUser()
        Dim userName As String = ""
        Dim currentUserPassword As String = ""
        allTheUsers = getAllUsersByFacebookId()
        If doesUserExist(allTheUsers, facebookId) = False Then
            'Create a new user
            Dim newUser = Membership.Provider.CreateUser(tb_username.Text, "facebookuser", email, "how do i login", "facebook", False, Nothing, MembershipCreateStatus.Success)
            Dim newPassword As String = newUser.ResetPassword()
            joinUserNameAndFacebookId(tb_username.Text, facebookId)
            createUserProfile()
            assignRole()
            'FormsAuthentication.RedirectFromLoginPage(facebookId, True)
            sendEmail()
        End If
    End Sub

    Function getAllUniEmailIds() As Array
        Dim allUniEmailIds As New List(Of String)
        Dim sql As String = "SELECT UniversityEmail FROM Student"
        Dim cmd As OleDbCommand = New OleDbCommand(sql, conn)
        conn.Open()
        Dim dbread = cmd.ExecuteReader()
        While (dbread.Read())
            allUniEmailIds.Add(dbread("UniversityEmail"))
        End While
        conn.Close()
        Dim sql2 As String = "SELECT UniversityEmail FROM Lecturer"
        Dim cmd2 As OleDbCommand = New OleDbCommand(sql2, conn)
        conn.Open()
        Dim dbread2 = cmd2.ExecuteReader()
        While (dbread2.Read())
            allUniEmailIds.Add(dbread2("UniversityEmail"))
            End While
        conn.Close()
        Return allUniEmailIds.ToArray()
    End Function

    Function getAllFbEmailIds() As Array
        Dim allFbEmailIds As New List(Of String)
        Dim sql As String = "SELECT FacebookEmail FROM Student"
        Dim cmd As OleDbCommand = New OleDbCommand(sql, conn)
        conn.Open()
        Dim dbread = cmd.ExecuteReader()
        While (dbread.Read())
            allFbEmailIds.Add(dbread("FacebookEmail"))
        End While
        conn.Close()
        Dim sql2 As String = "SELECT FacebookEmail FROM Lecturer"
        Dim cmd2 As OleDbCommand = New OleDbCommand(sql2, conn)
        conn.Open()
        Dim dbread2 = cmd2.ExecuteReader()
        While (dbread2.Read())
            allFbEmailIds.Add(dbread2("FacebookEmail"))
        End While
        conn.Close()
        Return allFbEmailIds.ToArray()
    End Function

    Function emailAlreadyRegistered(ByVal emailArray As Array, ByVal givenEmail As String)
        For Each existingEmail As String In emailArray
            If existingEmail = givenEmail Then
                Return True
            End If
        Next
        Return False
    End Function

    Function isUniEmail(ByVal email As String, ByVal domain As String)
        userEmail = tb_uniEmail.Text
        If userEmail.Length > 13 Then
            siteAddress = userEmail.Substring(userEmail.Length - 11)
            If siteAddress = domain Then
                'User is a member of the university
                Return True
            End If
        End If
        Return False
    End Function

    Sub joinUserNameAndFacebookId(ByVal userName As String, ByVal facebookId As String)
        Dim insertDetailsSql As String = "INSERT INTO UserFacebookIdJunction(UserId, UserName, FacebookId) VALUES(@UserId, @UserName, @FacebookId)"
        Dim insertDetailsCmd As New OleDbCommand(insertDetailsSql, conn)
        insertDetailsCmd.Parameters.AddWithValue("@UserId", getUserId(tb_username.Text))
        insertDetailsCmd.Parameters.AddWithValue("@UserName", tb_username.Text)
        insertDetailsCmd.Parameters.AddWithValue("@FacebookId", facebookId)
        conn.Open()
        insertDetailsCmd.ExecuteNonQuery()
        conn.Close()
    End Sub

    Sub createUserProfile()
        If RadioButtonList1.SelectedValue = 3 Then
            'User is a student
            Dim studentProfileSql As String = "INSERT INTO Student(FirstName, LastName, StudentNumber, FacebookEmail, UserName, Fkid_UserId, Phone, Fkid_Course, UniversityName, UniversityEmail) VALUES(@FirstName, @LastName, @StudentNumber, @FacebookEmail, @UserName, @Fkid_UserId, @Phone, @Fkid_Course, @UniversityName, @UniversityEmail)"
            Dim studentProfileCmd As New OleDbCommand(studentProfileSql, conn)
            studentProfileCmd.Parameters.AddWithValue("@FirstName", firstName)
            studentProfileCmd.Parameters.AddWithValue("@LastName", lastName)
            studentProfileCmd.Parameters.AddWithValue("@StudentNumber", tb_studentNumber.Text)
            studentProfileCmd.Parameters.AddWithValue("@FacebookEmail", email)
            studentProfileCmd.Parameters.AddWithValue("@UserName", tb_username.Text)
            studentProfileCmd.Parameters.AddWithValue("@Fkid_UserId", getUserId(tb_username.Text))
            studentProfileCmd.Parameters.AddWithValue("@Phone", tb_contact.Text)
            studentProfileCmd.Parameters.AddWithValue("@Fkid_Course", dd_chooseCourse.SelectedIndex)
            studentProfileCmd.Parameters.AddWithValue("@UniversityName", 1)
            studentProfileCmd.Parameters.AddWithValue("@UniversityEmail", tb_uniEmail.Text)
            conn.Open()
            studentProfileCmd.ExecuteNonQuery()
            conn.Close()
        ElseIf RadioButtonList1.SelectedValue = 2 Then
            'User is a lecturer
            Dim lecturerProfileSql As String = "INSERT INTO Lecturer(FirstName, LastName, FacebookEmail, ExtensionNumber, EmployeeNumber, Fkid_Faculty, UserName, Fkid_UserId, UniversityName, UniversityEmail) VALUES(@FirstName, @LastName, @FacebookEmail, @ExtensionNumber, @EmployeeNumber, @Fkid_Faculty, @UserName, @Fkid_UserId, @UniversityName, @UniversityEmail)"
            Dim lecturerProfileCmd As New OleDbCommand(lecturerProfileSql, conn)
            lecturerProfileCmd.Parameters.AddWithValue("@FirstName", tb_firstname.Text)
            lecturerProfileCmd.Parameters.AddWithValue("@LastName", tb_lastname.Text)
            lecturerProfileCmd.Parameters.AddWithValue("FacebookEmail", email)
            lecturerProfileCmd.Parameters.AddWithValue("@ExtensionNumber", tb_contact.Text)
            lecturerProfileCmd.Parameters.AddWithValue("@EmployeeNumber", tb_employeeNumber.Text)
            lecturerProfileCmd.Parameters.AddWithValue("@Fkid_Faculty", ddc_chooseFaculty.SelectedIndex)
            lecturerProfileCmd.Parameters.AddWithValue("@UserName", tb_username.Text)
            lecturerProfileCmd.Parameters.AddWithValue("Fkid_UserId", getUserId(tb_username.Text))
            lecturerProfileCmd.Parameters.AddWithValue("@UniversityName", 1)
            lecturerProfileCmd.Parameters.AddWithValue("@UniversityEmail", tb_uniEmail.Text)
            conn.Open()
            lecturerProfileCmd.ExecuteNonQuery()
            conn.Close()
        Else
            Return
        End If

    End Sub

    Sub assignRole()
        Try
        If RadioButtonList1.SelectedValue = 3 Then
            'User is a student
            Dim studentRoleSql As String = "INSERT INTO aspnet_UsersInRoles(UserId, RoleId) Values(@UserId, @RoleId)"
            Dim studentRoleCmd As OleDbCommand = New OleDbCommand(studentRoleSql, conn)
                studentRoleCmd.Parameters.AddWithValue("@UserId", getUserId(tb_username.Text))
                studentRoleCmd.Parameters.AddWithValue("@RoleId", 3)
                conn.Open()
                studentRoleCmd.ExecuteNonQuery()
                conn.Close()
        ElseIf RadioButtonList1.SelectedValue = 2 Then
            'User is a lecturer
            Dim lecturerRoleSql As String = "INSERT INTO aspnet_UsersInRoles(UserId, RoleId) VALUES(@UserId, @RoleId)"
            Dim lecturerRoleCmd As OleDbCommand = New OleDbCommand(lecturerRoleSql, conn)
                lecturerRoleCmd.Parameters.AddWithValue("@UserId", getUserId(tb_username.Text))
                lecturerRoleCmd.Parameters.AddWithValue("@RoleId", 2)
                conn.Open()
                lecturerRoleCmd.ExecuteNonQuery()
                conn.Close()
            End If
        Catch ex As Exception
            Return
        End Try

    End Sub

    Protected Sub EmailValidator_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles EmailValidator.ServerValidate
        allTheUniEmailIds = getAllUniEmailIds()
        If emailAlreadyRegistered(allTheUniEmailIds, tb_uniEmail.Text) Then
            args.IsValid = False
            EmailValidity.InnerText = "Email is already registered"
            EmailValidity.Attributes.Add("class", "taken")
        ElseIf isUniEmail(tb_uniEmail.Text, "herts.ac.uk") = False Then
            args.IsValid = False
            EmailValidity.InnerText = "Please enter your university email"
            EmailValidity.Attributes.Add("class", "taken")
        Else
            args.IsValid = True
            EmailValidity.InnerText = "Email is available"
            EmailValidity.Attributes.Add("class", "available")
        End If
    End Sub

    Protected Sub UsernameValidator_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles UsernameValidator.ServerValidate
        allTheUsers = getAllUsers()
        If doesUserExist(allTheUsers, tb_username.Text) Then
            'Display a username taken message
            args.IsValid = False
            Else
            'Display a username available message
            args.IsValid = True
        End If
    End Sub

    Sub sendEmail()
        Dim baseUrl As String = Request.Url.GetLeftPart(UriPartial.Authority) & Request.ApplicationPath
        Dim verifyUrl As String = "VerifyNewUser.aspx?UserId=" & getUserId(tb_username.Text)
        Dim fullPath As String = baseUrl & verifyUrl
        Dim appPath As String = Request.PhysicalApplicationPath
        Dim reader As StreamReader = New StreamReader(appPath & "EmailTemplates/VerifyNewUser.txt")
        Dim mailMessage As MailMessage = New MailMessage()
        mailMessage.IsBodyHtml = True
        mailMessage.From = New MailAddress("ari.dk.roy@gmail.com")
        mailMessage.To.Add(New MailAddress(tb_uniEmail.Text))
        mailMessage.CC.Add(New MailAddress("ari.dk.roy@gmail.com"))
        mailMessage.Subject = "Please confirm you registration"
        mailMessage.Body = reader.ReadToEnd()
        reader.Close()
        mailMessage.Body = mailMessage.Body.Replace("<%UserName%>", tb_username.Text)
        mailMessage.Body = mailMessage.Body.Replace("<%VerificationLink%>", fullPath)
        Dim client As SmtpClient = New SmtpClient()
        client.EnableSsl = True
        client.Send(mailMessage)
    End Sub

    Protected Sub deleteUser(ByVal userId As Integer)
        Dim sqlDeleteMembership As String = "DELETE * FROM aspnet_Membership WHERE UserId = @UserId"
        Dim cmdDeleteMembership As OleDbCommand = New OleDbCommand(sqlDeleteMembership, conn)
        cmdDeleteMembership.Parameters.AddWithValue("@UserId", userId)
        Dim sqlDeleteUser As String = "DELETE * FROM aspnet_Users WHERE UserId = @UserId"
        Dim cmdDeleteUser As OleDbCommand = New OleDbCommand(sqlDeleteUser, conn)
        cmdDeleteUser.Parameters.AddWithValue("@UserId", userId)
        Dim sqlDeleteRole As String = "DELETE * FROM aspnet_UsersInRoles WHERE UserId = @UserId"
        Dim cmdDeleteRole As OleDbCommand = New OleDbCommand(sqlDeleteRole, conn)
        cmdDeleteRole.Parameters.AddWithValue("@UserId", userId)
        Dim sqlDeleteStudent As String = "DELETE * FROM Student WHERE Fkid_UserId = @UserId"
        Dim cmdDeleteStudent As OleDbCommand = New OleDbCommand(sqlDeleteStudent, conn)
        cmdDeleteStudent.Parameters.AddWithValue("@Fkid_UserId", userId)
        Dim sqlDeleteLecturer As String = "DELETE * FROM Lecturer WHERE Fkid_UserId = @UserId"
        Dim cmdDeleteLecturer As OleDbCommand = New OleDbCommand(sqlDeleteLecturer, conn)
        cmdDeleteLecturer.Parameters.AddWithValue("@Fkid_UserId", userId)
        Dim sqlDeleteFbId As String = "DELETE * FROM UserFacebookIdJunction WHERE UserId = @UserId"
        Dim cmdDeleteFbId As OleDbCommand = New OleDbCommand(sqlDeleteFbId, conn)
        cmdDeleteFbId.Parameters.AddWithValue("@UserId", userId)
        conn.Open()
        cmdDeleteMembership.ExecuteNonQuery()
        cmdDeleteUser.ExecuteNonQuery()
        cmdDeleteRole.ExecuteNonQuery()
        If RadioButtonList1.SelectedValue = 3 Then
            cmdDeleteStudent.ExecuteNonQuery()
        ElseIf RadioButtonList1.SelectedValue = 2 Then
            cmdDeleteLecturer.ExecuteNonQuery()
        End If
        cmdDeleteFbId.ExecuteNonQuery()
        conn.Close()
    End Sub
End Class